﻿using System;
using System.Runtime.Serialization;


namespace Qetza.TeamFoundation.WorkItemQuery.Admin
{
    /// <summary>
    /// The exception that is thrown when a parameter provided to a command is not valid.
    /// </summary>
    public class InvalidParameterException : Exception
    {
        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="InvalidParameterException"/> class.
        /// </summary>
        /// <overloads>
        /// Initializes a new instance of the <see cref="InvalidParameterException"/> class.
        /// </overloads>
        public InvalidParameterException()
            : base()
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InvalidParameterException"/> class with a specified error message.
        /// </summary>
        /// <param name="message">
        /// The error message that explains the reason for the exception.
        /// </param>
        public InvalidParameterException(string message)
            : base(message)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InvalidParameterException"/> class with a specified error message 
        /// and the name of the invalid parameter.
        /// </summary>
        /// <param name="message">
        /// The error message that explains the reason for the exception.
        /// </param>
        /// <param name="parameterName">
        /// The name of the invalid parameter that caused the current exception.
        /// </param>
        public InvalidParameterException(string message, string parameterName)
            : base(message)
        {
            this.ParameterName = parameterName;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InvalidParameterException"/> class with a specified error message 
        /// and a reference to the inner exception that is the cause of this exception.
        /// </summary>
        /// <param name="message">
        /// The error message that explains the reason for the exception.
        /// </param>
        /// <param name="innerException">
        /// The exception that is the cause of the current exception. If the <paramref name="innerException"/> parameter 
        /// is not a null reference, the current exception is raised in a catch block that handles the inner exception.
        /// </param>
        public InvalidParameterException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InvalidParameterException"/> class with a specified error message, 
        /// the invalid parameter name, and a reference to the inner exception that is the cause of this exception.
        /// </summary>
        /// <param name="message">
        /// The error message that explains the reason for the exception.
        /// </param>
        /// <param name="parameterName">
        /// The name of the invalid parameter that caused the current exception.
        /// </param>
        /// <param name="innerException">
        /// The exception that is the cause of the current exception. If the <paramref name="innerException"/> parameter 
        /// is not a null reference, the current exception is raised in a catch block that handles the inner exception.
        /// </param>
        public InvalidParameterException(string message, string parameterName, Exception innerException)
            : base(message, innerException)
        {
            this.ParameterName = parameterName;
        }


        /// <summary>
        /// Initializes a new instance of the <see cref="InvalidParameterException"/> class with serialized data.
        /// </summary>
        /// <param name="info">
        /// The object that holds the serialized object data.
        /// </param>
        /// <param name="context">
        /// The contextual information about the source or destination.
        /// </param>
        protected InvalidParameterException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            this.ParameterName = info.GetString("ParameterName");
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the name of the invalid parameter.
        /// </summary>
        /// <value>
        /// The parameter name.
        /// </value>
        public string ParameterName { get; private set; }

        #endregion

        #region Methods

        /// <inheritdoc />
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }

            base.GetObjectData(info, context);
            info.AddValue("ParameterName", this.ParameterName, typeof(string));
        }

        #endregion
    }
}
